View Javadoc
1 /* 2 * Title: S/MIME Project 3 * Description: S/MIME email sending capabilities 4 * @Author Vladimir Radisic 5 * @Version 2.0.1 6 */ 7 8 package org.webdocwf.util.smime.der; 9 10 11 import org.webdocwf.util.smime.exception.SMIMEException; 12 import org.webdocwf.util.smime.exception.ErrorStorage; 13 14 15 /*** 16 * Every element of data represented in ASN.1 notation should be encoded 17 * in the process of implementation. It can be done according to BER (Basic 18 * Encoding Rules) or according to DER (Distinguish Encoding Rules). DERObject 19 * class is the root class (super class) of all classes used in DER encodings 20 * of variety elements in data structures used by SMIME.<BR> 21 * <BR> 22 * DER encoding of elements can be performed in two forms: definite form and 23 * indefinite form. DERObject class represents definite form of encoding. Every 24 * encoded element, according to this rules, involves three parts: Identifier 25 * Octet (which represents Tag Type of the encoding data), Length Octets (one 26 * or more octets with the information about number of octets (bytes) in the 27 * content), and Content Octets (they represent data which have to be DER 28 * encoded). <BR> 29 * <BR> 30 * DERObject can be structured or primitive, which depends on his content. 31 */ 32 public class DERObject { 33 34 /*** 35 * Identifier octet of DER encoding element. It must be in the range 0-255. 36 */ 37 private int identifierOctet; 38 39 /*** 40 * Length Octets of DER encoding element. 41 */ 42 private String lengthOctets = ""; 43 44 /*** 45 * Content Octets of DER encoding element. 46 */ 47 private String contentOctets = ""; 48 49 /*** 50 * Type of element number (part of Identifier Octet). It must be in the 51 * range 0-30. 52 */ 53 private int tagTypeNumber = 0; 54 55 /*** 56 * Class Type of element (part of Identifier Octet). It can have values: 57 * 0-Universal, 64-Application, 128-Context, 192-Private (Default 0) 58 */ 59 private int tagClassType = 0; 60 61 /*** 62 * Complexity type of element. It can have values: 0-Primitive, 32-Structured 63 * (Default 0) 64 */ 65 private int tagComplexity = 0; 66 67 /*** 68 * Total lenght (number of octets) of DER object (Default 0) 69 */ 70 private int totalLength = 0; 71 72 /*** 73 * Creates DER Object with defined value for identifier octet. 74 * @param identifierOctet0 must be in the range 0-255 (whithouth 31) 75 * @exception SMIMEException in case of invalid identifierOctet0 parameter 76 */ 77 public DERObject(int identifierOctet0) throws SMIMEException { 78 if (identifierOctet0 < 0) 79 throw new SMIMEException(this, 1000); 80 else if (identifierOctet0 > 255) 81 throw new SMIMEException(this, 1001); 82 else if ((identifierOctet0 & 31) == 31) 83 throw new SMIMEException(this, 1002); 84 identifierOctet = identifierOctet0; 85 tagClassType = identifierOctet0 & 192; 86 tagComplexity = identifierOctet0 & 32; 87 tagTypeNumber = identifierOctet0 & 31; 88 totalLength = 1; // Current length of DER object (contain only Identifier octet) 89 } 90 91 /*** 92 * Creates DER Object with defined value for identifier octet and values of 93 * content octets 94 * @param identifierOctet0 must be in the range 0-255 (whithouth 31) 95 * @param content0 content of DER Object 96 * @exception SMIMEException in case of invalid identifierOctet0 parameter, 97 * or in case of adding content to DER object of type Null DER object 98 */ 99 public DERObject(int identifierOctet0, byte[] content0) throws SMIMEException { 100 this(identifierOctet0); 101 this.addContent(content0); 102 } 103 104 /*** 105 * Defines the Lenght Octets which is the part of DEROctet 106 * @param len0 number of octets in the content 107 * @return String representation of Length Octets that correspond to len0 number 108 * @exception SMIMEException caused by non SMIMEException which is: 109 * UnsupportedEncodingException. 110 */ 111 private String lengthDERPart(int len0) throws SMIMEException { 112 String returnString = null; 113 114 if (len0 < 128) { 115 byte[] lenByte = new byte[1]; 116 117 lenByte[0] = (byte) len0; 118 try { 119 returnString = new String(lenByte, "ISO-8859-1"); 120 } catch (Exception e) { 121 throw SMIMEException.getInstance(this, e, "lengthDERPart"); 122 } 123 return returnString; 124 } else { 125 int i = 1, a = 1; // i: Number of required bits in length0 number 126 127 for (; (a * 2) <= len0; i++) 128 a = a * 2; 129 i = (int) Math.ceil((double) i / 8); // Number of required bytes for holding length data 130 byte[] lenByte = new byte[i + 1]; // + 1 for first byte in length string 131 132 lenByte[0] = (byte) (i); // First byte define number of following bytes used for holding length data 133 lenByte[0] = (byte) ((int) lenByte[0] | 128); // Indicate complex length octets with bit #8 set to 1 134 for (; i > 0; i--) { 135 a = 255 << ((lenByte.length - i - 1) * 8); 136 lenByte[i] = (byte) ((len0 & a) >> ((lenByte.length - i - 1) * 8)); 137 } 138 try { 139 returnString = new String(lenByte, "ISO-8859-1"); 140 } catch (Exception e) { 141 throw SMIMEException.getInstance(this, e, "lengthDERPart"); 142 } 143 return returnString; 144 } 145 } 146 147 /*** 148 * Adds content to DER Object. Used only when the content isn't added earlier 149 * via second type of constructor in DERObject. 150 * @param content0 content octets for adding to DERObject 151 * @exception SMIMEException when adding content to DER object is of type 152 * Null DER object. Also, it can be caused by non SMIMEException which is: 153 * UnsupportedEncodingException. 154 */ 155 void addContent(byte[] content0) throws SMIMEException { 156 if (identifierOctet == 5) 157 throw new SMIMEException(this, 1003); 158 try { 159 contentOctets = contentOctets.concat(new String(content0, "ISO-8859-1")); 160 lengthOctets = lengthDERPart(contentOctets.length()); 161 totalLength = 1 + contentOctets.length() + lengthOctets.length(); 162 } catch (Exception e) { 163 throw SMIMEException.getInstance(this, e, "addContent"); 164 } 165 } 166 167 /*** 168 * Returns DER encoded object 169 * @return DERObject as byte array 170 * @exception SMIMEException if content of DER object is absent. Also, it can be 171 * caused by non SMIMEException which is: UnsupportedEncodingException. 172 */ 173 public byte[] getDEREncoded() throws SMIMEException { 174 if (totalLength == 1 && identifierOctet != 5) 175 throw new SMIMEException(this, 1004); 176 byte[] returnByteArray = null; // Variable for returning DER encoding object represented as byte array 177 178 try { 179 byte[] temp = { 180 (byte) identifierOctet 181 }; // Import identifier octet in DER object string (first byte of string) 182 String derOctet = new String(temp, "ISO-8859-1"); // String with returning DER value 183 184 if (identifierOctet == 5) // Special DER format is for Null DER object 185 { 186 temp[0] = (byte) 0x00; 187 contentOctets = contentOctets.concat(new String(temp, "ISO-8859-1")); 188 derOctet = derOctet.concat(contentOctets); 189 totalLength = 2; 190 returnByteArray = derOctet.getBytes("ISO-8859-1"); // Null DER value 191 } else { 192 derOctet = derOctet.concat(lengthOctets).concat(contentOctets); 193 totalLength = 1 + contentOctets.length() + lengthOctets.length(); 194 returnByteArray = derOctet.getBytes("ISO-8859-1"); 195 } 196 } catch (Exception e) { 197 throw SMIMEException.getInstance(this, e, "getDEREncoded"); 198 } 199 return returnByteArray; 200 } 201 202 /*** 203 * Returns Identifier Octet 204 * @return Identifier Octet in the range 0-255 205 */ 206 public int getIdentifierOctet() { 207 return identifierOctet; 208 } 209 210 /*** 211 * Returns Tag Type 212 * @return Tag Type in the range 0-30 213 */ 214 public int getTagTypeNumber() { 215 return tagTypeNumber; 216 } 217 218 /*** 219 * Returns Class Type 220 * @return 0-Universal, 64-Application, 128-Context, 192-Private (Default 0) 221 */ 222 public int getTagClassType() { 223 return tagClassType; 224 } 225 226 /*** 227 * Returns Tag Complexity 228 * @return 0-primitive, 32-structured (Default 0) 229 */ 230 public int getTagComplexity() { 231 return tagComplexity; 232 } 233 234 /*** 235 * Returns size of content part in DER object (Number of content octets). 236 * @return Number of content octets in DER encoded object 237 */ 238 public int getContentPartSize() { 239 return contentOctets.length(); 240 } 241 242 /*** 243 * Returns size of length part in DER object (Number of length octets). 244 * @return Number of length octets in DER encoded object 245 */ 246 public int getLengthPartSize() { 247 return lengthOctets.length(); 248 } 249 250 /*** 251 * Return content octets part from DER object. 252 * @return Number of content octets in DER encoded object 253 * @exception SMIMEException caused by non SMIMEException which is: 254 * UnsupportedEncodingException . 255 */ 256 public byte[] getContentOctets() throws SMIMEException { 257 byte[] returnByteArray = null; 258 259 try { 260 returnByteArray = contentOctets.getBytes("ISO-8859-1"); 261 } catch (Exception e) { 262 throw SMIMEException.getInstance(this, e, "getContentOctets"); 263 } 264 return returnByteArray; 265 } 266 267 /*** 268 * Return length octets part from DER object. 269 * @return Number of length octets in DER encoded object 270 * @exception SMIMEException caused by non SMIMEException which is: 271 * UnsupportedEncodingException. 272 */ 273 public byte[] getLengthOctets() throws SMIMEException { 274 byte[] returnByteArray = null; 275 276 try { 277 returnByteArray = lengthOctets.getBytes("ISO-8859-1"); 278 } catch (Exception e) { 279 throw SMIMEException.getInstance(this, e, "getLengthOctets"); 280 } 281 return returnByteArray; 282 } 283 284 /*** 285 * Returns total length of DER object 286 * @return Total length of DER Object (involves identifier octet, length 287 * octets and content octets) 288 */ 289 public int getTotalSize() { 290 if (tagTypeNumber == 5) 291 return totalLength + 1; 292 return totalLength; 293 } 294 } 295

This page was automatically generated by Maven